<script>
import Space from '@c/Space'
import { mapConstants } from '@/libs/constants'

const formInputLayout = {
  labelCol: { span: 0 },
  wrapperCol: { span: 30 },
};
const formSelectLayout = {
  labelCol: { span: 0 },
  wrapperCol: { span: 23 },
};
const formDatetimeLayout = {
  labelCol: { span: 5 },
  wrapperCol: { span: 30 },
};
export default {
  name: 'SearchForm',
  components: { 
    Space,
  },
  data() {
    return {
      form: {},
      show: false
    }
  },
  computed: {
    ...mapConstants(['CONFIG_TYPES']),
    anyQuery() {
      return this.fields.some(i => {
        if (this.$route.query[i.field]) {
          return true
        }
      })
    },
  },
  props: {
    fields: Array,
    /**
     * 筛选后，重置当前页到第一页
     */
    resetCurrentPage: {
      type: Boolean,
      default: true,
    },
    popover: {
      type: Boolean,
      default: true,
    },
    maxWidth: {
      type: String,
      default: '700px',
    },
    showSearch: {
      type: Boolean,
      default: false
    },
  },
  methods: {
    async onSubmit() {
      const query = { ...this.$route.query }
      if (this.resetCurrentPage) {
        delete query.page
      }

      // 构建查询对象, 空值的不放入, 保留非搜索表单的 query 字段
      this.fields.forEach(i => {
        const key = i.field
        let val = this.form[key]
        if (typeof val === 'string') {
          val = val.trim()
        }
        if (val === '' || val === undefined) {
          delete query[key]
        } else {
          query[key] = val
        }
      })

      try {
        await this.$router.push({
          path: this.$route.path,
          query,
        })
      } catch (e) {
        if (e.name !== 'NavigationDuplicated') {
          throw e
        }
      }
    },
    onRefresh() {
      this.$router.replace({
        path: this.$route.fullPath,
        query: {
          _refresh: Date.now(),
        },
      })
    },
    onReset() {
      this.form = {}
      this.onSubmit()
    },
    setFormValueFromQuery() {
      const query = this.$route.query      
      this.fields.forEach(i => {
        const key = i.field
        const val = query[key]
        this.$set(this.form, key, val)
      })
    },
  },
  watch: {
    $route: {
      handler() {
        if(this.show) {
          this.setFormValueFromQuery()
        }
      },
      immediate: true,
    },
    showSearch: {
      handler(val) {
        this.show = val;
        if(this.show) {
          this.setFormValueFromQuery()
        }
      },
      immediate: true
    }
  },

  render(h) {
    let searchForm = <a-form
        layout="inline"
        v-on:keydown_enter_native_prevent={this.onSubmit}
      >
        {
          this.fields.map((item) => {
            let c
            item.width = 'width:200px'
            item.form_label = ''
            if (item.label) {
              c = (
                <a-input
                  v-model={this.form[item.field]}
                  placeholder={item.label}
                  allow-clear
                />
              )
              item.labelCol = formInputLayout.labelCol
              item.wrapperCol = formInputLayout.wrapperCol
              switch (item.type) {
                case this.CONFIG_TYPES.CASCADER:
                  c = (
                    <a-cascader
                      v-model={this.form[item.field]}
                      options={item.options.options}
                      placeholder={item.label}
                    />
                  )
                  item.width = 'width:200px'
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
                case this.CONFIG_TYPES.SELECT_TREE:
                  item.width = 'width:200px'
                  c = (
                    <a-select
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      allow-clear
                      show-search
                      option-filter-prop="title"
                      option-label-prop="title"
                    >
                      {
                        item.options.options.map((i) => {
                          const value = String(i[item.valueField || 'id'])
                          return (<a-select-option title={i.title} value={value}>{i.text}</a-select-option>)
                        })
                      }
                    </a-select>
                  )
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
                case this.CONFIG_TYPES.DATE:
                  if (item.filter_rules && item.filter_rules.indexOf('between') !== -1) {
                    c = (
                      <a-range-picker
                        default-value={this.form[item.field]}
                        v-model={this.form[item.field]}
                        placeholder={item.label}
                        value-format='YYYY-MM-DD'
                        allow-clear
                      />
                    )
                  } else {
                    c = (
                      <a-date-picker
                        default-value={this.form[item.field]}
                        v-model={this.form[item.field]}
                        placeholder={item.label}
                        value-format='YYYY-MM-DD'
                        allow-clear
                      />
                    )  
                  } 
                  item.width = 'width:200px'
                  item.labelCol = formDatetimeLayout.labelCol
                  item.wrapperCol = formDatetimeLayout.wrapperCol
                  break
                case this.CONFIG_TYPES.TIME:
                  c = (
                    <a-time-picker
                      default-value={this.form[item.field]}
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      format="HH:mm"
                      allow-clear
                    />
                  )
                  
                  item.width = 'width:200px'
                  item.labelCol = formDatetimeLayout.labelCol
                  item.wrapperCol = formDatetimeLayout.wrapperCol
                  break
                case this.CONFIG_TYPES.DATETIME:
                  if (item.filter_rules && item.filter_rules.indexOf('between') !== -1) {
                    c = (
                      <a-range-picker
                        default-value={this.form[item.field]}
                        v-model={this.form[item.field]}
                        placeholder={item.label}
                        value-format='YYYY-MM-DD HH:mm:ss'
                        show-time
                        allow-clear
                      />
                    )
                  } else {
                    c = (
                      <a-date-picker
                        default-value={this.form[item.field]}
                        v-model={this.form[item.field]}
                        placeholder={item.label}
                        value-format='YYYY-MM-DD HH:mm:ss'
                        show-time
                        allow-clear
                      />
                    )  
                  } 
                  item.width = 'width:200px'
                  item.labelCol = formDatetimeLayout.labelCol
                  item.wrapperCol = formDatetimeLayout.wrapperCol
                  break
                case this.CONFIG_TYPES.SINGLE:
                case this.CONFIG_TYPES.MULTIPLE:
                  if (item.options && item.options.type) {
                    switch (item.options.type) {
                      case 'single_box':
                      case 'single_select':
                        c = (
                          <a-select
                            default-value={this.form[item.field]}
                            v-model={this.form[item.field]}
                            placeholder={item.label}
                            allow-clear
                            show-search
                            option-filter-prop="text"
                          >
                            {
                              item.options.options.map((i) => {
                                const value = String(i[item.valueField || 'id'])
                                const text = i[item.labelField || 'name']
                                return (<a-select-option text={text} value={value}>{text}</a-select-option>)
                              })
                            }
                          </a-select>
                        )
                        item.labelCol = formSelectLayout.labelCol
                        item.wrapperCol = formSelectLayout.wrapperCol
                        break
                      case 'multiple_box':
                      case 'multiple_select':
                      case 'transfer': 
                        c = (
                          <a-select
                            mode="multiple"
                            show-arrow
                            v-model={this.form[item.field]}
                            default-value="this.form[item.field] || []" // 注意：默认值应该是一个空数组
                            placeholder={item.label}
                            allow-clear
                            show-search
                            option-filter-prop="text"
                          >
                            {item.options.options.map((i) => {
                              const value = String(i[item.valueField || "id"]);
                              const text = i[item.labelField || "name"];
                              return (
                                <a-select-option key={value} text={text} value={value}>{text}</a-select-option>
                              );
                            })}
                          </a-select>
                        )
                        item.labelCol = formSelectLayout.labelCol
                        item.wrapperCol = formSelectLayout.wrapperCol
                        break
                    }
                  }
                  break
              }
              switch (item.filter_rules) {
                case '[\"null\"]':
                  c = (
                    <a-select 
                      default-value={this.form[item.field]}
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      allow-clear
                      show-search
                      option-filter-prop="text"
                    >
                      <a-select-option value='true'>无{item.label}</a-select-option>
                      <a-select-option value='false'>有{item.label}</a-select-option>
                    </a-select>
                  )
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
                case '[\"not null\"]':
                  c = (
                    <a-select 
                      default-value={this.form[item.field]}
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      allow-clear
                      show-search
                      option-filter-prop="text"
                    >
                      <a-select-option value='false'>无{item.label}</a-select-option>
                      <a-select-option value='true'>有{item.label}</a-select-option>
                    </a-select>
                  )
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
                case '[\"empty\"]':
                  c = (
                    <a-select 
                      default-value={this.form[item.field]}
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      allow-clear
                      show-search
                      option-filter-prop="text"
                    >
                      <a-select-option value='true'>{item.label}是空的</a-select-option>
                      <a-select-option value='false'>{item.label}不是空的</a-select-option>
                    </a-select>
                  )
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
                case '[\"not empty\"]':
                  c = (
                    <a-select 
                      default-value={this.form[item.field]}
                      v-model={this.form[item.field]}
                      placeholder={item.label}
                      allow-clear
                      show-search
                      option-filter-prop="text"
                    >
                      <a-select-option value='false'>{item.label}是空的</a-select-option>
                      <a-select-option value='true'>{item.label}不是空的</a-select-option>
                    </a-select>
                  )
                  item.labelCol = formSelectLayout.labelCol
                  item.wrapperCol = formSelectLayout.wrapperCol
                  break
              }
            }
              
            return (
              <a-form-item 
                style={item.width}
                key={item.field} 
                label={item.form_label} 
                label-col={item.labelCol} 
                wrapper-col={item.wrapperCol} 
              >
                {c}
              </a-form-item>
            )
          })
        }
        <a-form-item 
          class="actions" 
        >
          <space>
            <a-button type="primary" vOn:click={this.onSubmit}>搜索</a-button>
            <a-button vOn:click={this.onReset}>重置</a-button>
          </space>
        </a-form-item>
      </a-form>
    if (this.popover) {
      return (
        <a-popover
          trigger="click"
          placement="bottomLeft"
          overlay-style={{ padding: '10px', maxWidth: this.maxWidth }}
        >
          <template slot="content">
            {searchForm}
          </template>
          <a-button type={this.anyQuery ? 'primary' : ''}>搜索</a-button>
        </a-popover>
      )
    } else {
      return searchForm
    }     
  },
}
</script>

<style scoped lang="less">
.actions {
  display: block;
  margin-bottom: 0;
}

.ant-form-item {
  width: 200px;
}

::v-deep {
  .ant-calendar-range-picker-input {
    width: 48%;
  }
}
</style>